home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
asm
/
games
/
packman
/
pacman2.s
< prev
next >
Wrap
Text File
|
1980-01-03
|
26KB
|
1,126 lines
; part 3
; 'pacman2.s' source , see accompaning text in the July 1994 issue
; of Amiga computing . Written by Mark Jackson using Devpac 3.02
; this month I've added the background graphics , and (after hours of
; trying!) I finally got the movement routines to work the way I
; wanted them to . So now pacman moves in the paths , and for example
; when you're moving right along a path and press up , at then next
; opportunity pacman will go up a path! .
section pacman,code_c ; put in CHIP memory
; opt c-,o+ ; not case-sensitive
; optimisation on
move.l 4.w,a6 ; execbase
jsr forbid(a6) ; turn off multitasking!
lea $dff000,a5 ; a5 always points to
; register's base address
lea gfx_lib,a1 ; name of library to open
moveq #0,d0 ; version number unimportant
move.l 4.w,a6 ; execbase
jsr openlib(a6) ; open graphics-library
move.l d0,gfx_base ; save base address
move.l #screen,d0 ; address of first bitplane
move.w d0,pl1l ; set pointer low word
swap d0
move.w d0,pl1h ; and high word
move.l #screen+40*256,d0
move.w d0,pl2l
swap d0
move.w d0,pl2h
move.l #screen+40*256*2,d0
move.w d0,pl3l
swap d0
move.w d0,pl3h
move.l #sprite1,d0 ; address of sprite
move.w d0,sp0l ; set pointer low word
swap d0
move.w d0,sp0h ; and high word
move.l #sprite2,d0
move.w d0,sp1l
swap d0
move.w d0,sp1h
move.l gfx_base,a6 ; graphics-library base address
move.w #$80,dmacon(a5) ; turn copper dma off
move.l $32(a6),old_copper ; save address of old copper-list
move.l #new_copper,$32(a6) ; insert our new copper-list
move.w #$8080,dmacon(a5) ; and turn copper dma back on!
start_game: ; reset all variables ->
move.w #151,x ; pacman x-coordinate
move.w #156,y ; pacman y-coordinate
move.w #1,dir ; pacman direction
move.w #1,dir2 ; set other to same (see later)
move.w #0,score ; player's score
move.w #5,lives ; player's number of lives
bsr draw_lives ; draw the number of lives
bsr print_score
bsr draw_pacman ; put pacman on screen
bsr ready ; print 'are you ready?' and wait
main_loop:
move.b vhposr(a5),d0 ; get scanline
cmp.b #$ff,d0 ; reached line $ff?
bne.s main_loop ; not yet
bsr read_joystick ; read joystick and adjust coords
bsr draw_pacman ; put sprite in correct position
bsr animate_pacman ; animate sprite
bsr print_score
bsr draw_lives ; draw number of lives on screen
move.b $bfec01,d0 ; read keyboard (raw keycode)
eor.b #$ff,d0 ; decode byte
ror.b #1,d0
cmp.b #$45,d0 ; escape key pressed?
beq.s quit_game ; if so then quit game!
cmp.b #$10,d0 ; 'q' key pressed?
beq.s start_game ; if so then restart game
cmp.b #$19,d0 ; 'p' key pressed?
bne.s no_pause ; no - carry on
bsr pause_game ; else pause game
no_pause:
tst.w lives ; have player's lives reached zero?
bne.s main_loop ; nope - do loop again!
bsr game_over ; else print 'game over' , etc.
bra start_game ; and start again
quit_game:
move.l gfx_base,a6 ; graphics-library base address
move.w #$80,dmacon(a5) ; copper dma off
move.l old_copper,$32(a6) ; restore system copper-list
move.w #$8080,dmacon(a5) ; copper dma on
move.l gfx_base,a1 ; graphics-library base address
move.l 4.w,a6 ; execbase
jsr closelib(a6) ; close library
error:
move.l 4.w,a6 ; execbase
jsr permit(a6) ; multitasking on
moveq #0,d0 ; no errors , please!
rts ; and return to CLI
old_copper: ; space to store address of
dc.l 0 ; system copper-list
new_copper: ; our new copper-list
dc.w bplcon0,$3200 ; 5 bitplane (32 colour) screen
dc.w bplcon1,0 ; hardware-scroll value
dc.w bplcon2,$20 ; video priority
dc.w bpl1mod,0 ; bitplane modulo (odd bitplanes)
dc.w bpl2mod,0 ; bitplane modulo (even bitplanes)
dc.w ddfstrt,$38 ; left edge of screen
dc.w ddfstop,$d0 ; right edge of screen
dc.w diwstrt,$2c81 ; top left corner of screen
dc.w diwstop,$2cc1 ; bottom right corner of screen
dc.w bpl1pth ; bitplane pointers
pl1h: dc.w 0,bpl1ptl
pl1l: dc.w 0,bpl2pth
pl2h: dc.w 0,bpl2ptl
pl2l: dc.w 0,bpl3pth
pl3h: dc.w 0,bpl3ptl
pl3l: dc.w 0
dc.w spr0pth ; sprite pointers
sp0h: dc.w 0,spr0ptl
sp0l: dc.w 0,spr1pth
sp1h: dc.w 0,spr1ptl
sp1l: dc.w 0,spr2pth
sp2h: dc.w 0,spr2ptl
sp2l: dc.w 0,spr3pth
sp3h: dc.w 0,spr3ptl
sp3l: dc.w 0,spr4pth
sp4h: dc.w 0,spr4ptl
sp4l: dc.w 0,spr5pth
sp5h: dc.w 0,spr5ptl
sp5l: dc.w 0,spr6pth
sp6h: dc.w 0,spr6ptl
sp6l: dc.w 0,spr7pth
sp7h: dc.w 0,spr7ptl
sp7l: dc.w 0
dc.w colour0,$000 ; colours at top of screen
dc.w colour1,$fff
dc.w colour2,$ff0
dc.w colour3,$660
dc.w $3801,$ff00,colour0,$fff ; draw a little copper bar
dc.w $3901,$ff00,colour0,$666
dc.w $3a01,$ff00,colour0,$000
dc.w colour1,$000 ; main screen's colours
dc.w colour2,$fff
dc.w colour3,$f00
dc.w colour4,$332
dc.w colour5,$fff
dc.w colour6,$fff
dc.w colour7,$fff
dc.w colour18,$04e ; pacman's colours
dc.w colour19,$ff4
dc.w colour20,$ff0
dc.w colour21,$ee0
dc.w colour22,$dd0
dc.w colour23,$cc0
dc.w colour24,$bb0
dc.w colour25,$aa0
dc.w colour26,$05f
dc.w colour27,$03d
dc.w colour28,$02c
dc.w colour29,$eee
dc.w colour30,$ddd
dc.w colour31,$ccc
dc.w $ffff,$fffe ; end of copper-list
dc.w $ffff,$fffe ; (should be done twice!)
************ read joystick ************
read_joystick:
move.w $c(a5),d0 ; read joy0dat
btst #9,d0
beq.s l
move.w #0,dir2 ; set direction
l:
btst #1,d0
beq.s r
move.w #1,dir2 ; set direction
r:
move.w d0,d1 ; make copy of joy0dat
and.w #$3,d1 ; and out unwanted bits
cmp.w #$2,d1
beq.s down
cmp.w #$1,d1
bne.s d
down:
move.w #2,dir2 ; set direction
d:
and.w #$300,d0
cmp.w #$200,d0
beq.s up
cmp.w #$100,d0
bne.s u
up:
move.w #3,dir2 ; set direction
u:
rts
************ draw pacman ************
draw_pacman:
move.w dir2,d2 ; direction pac wants to go
bsr test_dir ; test if it's possible
tst.b d4 ; test flag
bne.s dir2_blocked ; it's not possible!
move.w dir2,dir ; if it is then set real dir
bra.s draw_pacman2 ; and draw pacman
dir2_blocked:
move.w dir,d2 ; pac's direction
bsr test_dir ; test if path is blocked
tst.b d4 ; test flag
beq.s draw_pacman2 ; if zero then ok to draw
rts ; else if set then skip
draw_pacman2:
move.w dir,d0 ; get direction (0-3)
lea dir_tab,a0 ; and direction table
lsl #2,d0 ; times 4
lea (a0,d0),a0 ; get start word
move.w (a0)+,dx ; set x speed
move.w (a0),dy ; and y speed
move.w dx,d0 ; get x-speed
move.w dy,d1 ; and y-speed
add.w d0,x ; add x-speed to x-coordinate
add.w d1,y ; add y-speed to y-coordinate
move.l #0,sprite1 ; clear control words
move.l #0,sprite2 ; and on second sprite
move.w x,d0 ; our x-coordinate (word)
move.w y,d1 ; and y-coordinate (word)
add.w #$80,d0 ; $80 = left edge of screen
add.w #$2c,d1 ; $2c = top edge of screen
move.w d1,d2 ; don't touch original value
move.b d2,sprite1 ; set y low 8 bits
add.w #$10,d2 ; add height of sprite
move.b d2,sprite1+$2 ; set 'last line' low 8 bits
move.w d0,d2 ; work on copy of x-coord
lsr #1,d2 ; shift right 1 bit
move.b d2,sprite1+$1 ; set x high 8 bits
move.w d1,d2 ; copy y-coord to 'd2'
and.w #$100,d2 ; and out unwanted bits
lsr #6,d2 ; shift right by 6 bits
or.b d2,sprite1+$3 ; set y high bit
add.w #$10,d1 ; add height of sprite
and.w #$100,d1 ; and out unwanted bits
lsr #7,d1 ; shift right by 7 bits
or.b d1,sprite1+$3 ; set 'last line' high bit
and.b #$1,d0 ; and out unwanted bits
or.b d0,sprite1+$3 ; set x low bit
move.l sprite1,sprite2 ; copy control words over
or.b #$80,sprite2+$3 ; and set 'attach' bit
rts
************ test direction ************
test_dir:
lea screen,a0 ; start of screen
move.w x,d0 ; pacman's x-coordinate
move.w y,d1 ; pacman's y-coordinate
move.w #0,d4 ; collision flag
test_left:
tst.w d2 ; is 'dir' zero?
bne test_right ; no - not going left
subq.w #1,d0 ; test pixels to pac's left
mulu #40,d1 ; y * 40 bytes per line
lea (a0,d1),a0 ; start line
move.w d0,d1 ; make copy of x-coord
lsr #3,d0 ; divided by 8 = no. bytes
lea (a0,d0),a0 ; point to start byte
lsl #3,d0 ; times 8 again
sub.w d0,d1 ; get number of pixel
move.w #7,d0 ; take this from 7
sub.w d1,d0 ; gives us bit number!
btst d0,(a0) ; test that bit
bne.s path_in_way_l ; if set then path in way
btst d0,40(a0) ; do this for all 16 lines
bne.s path_in_way_l
btst d0,40*2(a0)
bne.s path_in_way_l
btst d0,40*3(a0)
bne.s path_in_way_l
btst d0,40*4(a0)
bne.s path_in_way_l
btst d0,40*5(a0)
bne.s path_in_way_l
btst d0,40*6(a0)
bne.s path_in_way_l
btst d0,40*7(a0)
bne.s path_in_way_l
btst d0,40*8(a0)
bne.s path_in_way_l
btst d0,40*9(a0)
bne.s path_in_way_l
btst d0,40*10(a0)
bne.s path_in_way_l
btst d0,40*11(a0)
bne.s path_in_way_l
btst d0,40*12(a0)
bne.s path_in_way_l
btst d0,40*13(a0)
bne.s path_in_way_l
btst d0,40*14(a0)
bne.s path_in_way_l
btst d0,40*15(a0)
bne.s path_in_way_l
rts ; all clear!
path_in_way_l:
move.b #1,d4 ; set collision flag
rts ; and return
test_right:
cmp.w #1,d2 ; do same for right
bne test_down
add.w #16,d0
mulu #40,d1
lea (a0,d1),a0
move.w d0,d1
lsr #3,d0
lea (a0,d0),a0
lsl #3,d0
sub.w d0,d1
move.w #7,d0
sub.w d1,d0
btst d0,(a0)
bne.s path_in_way_r
btst d0,40(a0)
bne.s path_in_way_r
btst d0,40*2(a0)
bne.s path_in_way_r
btst d0,40*3(a0)
bne.s path_in_way_r
btst d0,40*4(a0)
bne.s path_in_way_r
btst d0,40*5(a0)
bne.s path_in_way_r
btst d0,40*6(a0)
bne.s path_in_way_r
btst d0,40*7(a0)
bne.s path_in_way_r
btst d0,40*8(a0)
bne.s path_in_way_r
btst d0,40*9(a0)
bne.s path_in_way_r
btst d0,40*10(a0)
bne.s path_in_way_r
btst d0,40*11(a0)
bne.s path_in_way_r
btst d0,40*12(a0)
bne.s path_in_way_r
btst d0,40*13(a0)
bne.s path_in_way_r
btst d0,40*14(a0)
bne.s path_in_way_r
btst d0,40*15(a0)
bne.s path_in_way_r
rts
path_in_way_r:
move.b #1,d4
rts
test_down:
cmp.w #2,d2
bne.s test_up
add.w #16,d1
mulu #40,d1
lea (a0,d1),a0
move.w d0,d1
lsr #3,d0
lea (a0,d0),a0
lsl #3,d0
sub.w d0,d1
move.w #7,d0
sub.w d1,d0
move.w #16-1,d3 ; test 16 pixels below...
t_down_loop:
btst d0,(a0) ; test bit
bne.s path_in_way_d ; if set then that's it!
tst.w d0 ; is bit no. zero?
beq.s overflow_d ; yes - need next byte
subq.w #1,d0 ; else next bit in byte
dbra d3,t_down_loop ; and loop back
rts
overflow_d:
move.w #7,d0 ; start bit = 7
lea 1(a0),a0 ; point to next byte
dbra d3,t_down_loop ; and loop back
rts
path_in_way_d:
move.b #1,d4
rts
test_up:
subq.w #1,d1 ; do same for up direction
mulu #40,d1
lea (a0,d1),a0
move.w d0,d1
lsr #3,d0
lea (a0,d0),a0
lsl #3,d0
sub.w d0,d1
move.w #7,d0
sub.w d1,d0
move.w #16-1,d3
t_up_loop:
btst d0,(a0)
bne.s path_in_way_u
tst.w d0
beq.s overflow_u
subq.w #1,d0
dbra d3,t_up_loop
rts
overflow_u:
move.w #7,d0
lea 1(a0),a0
dbra d3,t_up_loop
rts
path_in_way_u:
move.b #1,d4
rts
************ animate pacman ************
animate_pacman:
lea pacman_gfx,a0 ; start of pacman graphics
lea sprite1+$4,a1 ; the gfx part of sprite1
lea sprite2+$4,a2 ; the gfx part of sprite2
move.w dir,d0 ; direction of pacman (0-3)
mulu #16*4*2*10,d0 ; times length of gfx blocks
lea (a0,d0),a0 ; start of gfx data
addq.w #1,pacman_anim ; pacman animation number
cmp.w #10,pacman_anim ; have we reached end?
bne.s pacman_anim_ok ; nope - we're ok!
move.w #0,pacman_anim ; else reset anim number
pacman_anim_ok:
move.w pacman_anim,d0 ; get animation number
mulu #16*4*2,d0 ; times length of gfx block
lea (a0,d0),a0 ; this is the one!!!
move.w #16-1,d0 ; pacman = 16 lines high
pac_loop1:
move.l (a0)+,(a1)+ ; move in longword
dbra d0,pac_loop1 ; Decrement and BRAnch
move.w #16-1,d0 ; pacman = 16 lines high
pac_loop2:
move.l (a0)+,(a2)+ ; move in longword
dbra d0,pac_loop2 ; Decrement and BRAnch
rts
************ draw lives ************
draw_lives:
lea screen,a1 ; where to draw lives
move.w lives,d0 ; number of lives
subq.w #1,d0 ; take one , for dbra
lives_loop:
move.b #$44,(a1) ; draw little pacman!
move.b #$80,40(a1) ; first bitplane
move.b #$00,40*2(a1)
move.b #$00,40*3(a1)
move.b #$00,40*4(a1)
move.b #$80,40*5(a1)
move.b #$44,40*6(a1)
move.b #$7c,40*256(a1) ; and second bitplane
move.b #$ec,40*256+40(a1) ; (to give 4 colours)
move.b #$f8,40*256+40*2(a1)
move.b #$f0,40*256+40*3(a1)
move.b #$f8,40*256+40*4(a1)
move.b #$fc,40*256+40*5(a1)
move.b #$7c,40*256+40*6(a1)
lea 1(a1),a1 ; next byte on screen
dbra d0,lives_loop ; and repeat...
move.b #0,d0 ; put a zero in D0
move.b d0,(a1) ; and copy to screen
move.b d0,40(a1) ; this is quicker than
move.b d0,40*2(a1) ; 'move.b #0,(a1)' , etc.
move.b d0,40*3(a1)
move.b d0,40*4(a1)
move.b d0,40*5(a1)
move.b d0,40*6(a1)
move.b d0,40*7(a1)
move.b d0,40*256(a1) ; clear second bitplane too
move.b d0,40*256+40(a1)
move.b d0,40*256+40*2(a1)
move.b d0,40*256+40*3(a1)
move.b d0,40*256+40*4(a1)
move.b d0,40*256+40*5(a1)
move.b d0,40*256+40*6(a1)
move.b d0,40*256+40*7(a1)
rts
************ print score ************
print_score:
move.w score,d2 ; get score (stored in word)
digit4:
lea numbers,a0 ; start of numbers gfx data
cmp.w #1000,d2 ; compare 1000 to score
bge.s do_1000 ; score = 1000 or above
lea screen+18,a6 ; else print '0'
bsr print ; print it
bra.s digit3 ; and go onto next digit
do_1000:
divu.w #1000,d2 ; divide score by 1000
move.w d2,d3 ; save value
clr d2 ; clear
swap d2 ; swap words
lea (a0,d3),a0 ; get number
lea screen+18,a6 ; where to print
bsr.s print ; and print it
digit3:
lea numbers,a0
cmp.w #100,d2
bge.s do_100
lea screen+19,a6
bsr.s print
bra.s digit2
do_100:
divu.w #100,d2
move.w d2,d3
clr d2
swap d2
lea (a0,d3),a0
lea screen+19,a6
bsr.s print
digit2:
lea numbers,a0
cmp.w #10,d2
bge.s do_10
lea screen+20,a6
bsr.s print
bra.s digit1
do_10:
divu.w #10,d2
move.w d2,d3
clr d2
swap d2
lea (a0,d3),a0
lea screen+20,a6
bsr.s print
digit1:
lea numbers,a0
cmp.w #1,d2
bge.s do_1
lea screen+21,a6
bsr.s print
bra.s numbers_done
do_1:
lea (a0,d2),a0
lea screen+21,a6
bsr.s print
numbers_done:
rts
print:
move.b (a0),(a6)
move.b 10(a0),40(a6)
move.b 10*2(a0),40*2(a6)
move.b 10*3(a0),40*3(a6)
move.b 10*4(a0),40*4(a6)
move.b 10*5(a0),40*5(a6)
move.b 10*6(a0),40*6(a6)
move.b 10*7(a0),40*7(a6)
rts
************ are you ready? ************
ready:
lea screen+(40*110)+12,a0
lea gfx_buffer,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a0),a0 ; next bitplane on screen
lea 16*26(a1),a1 ; next bitplane in buffer
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea ready_gfx,a0
lea screen+(40*110)+12,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a1),a1 ; draw on next bitplane too!
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
ready_wait:
move.b vhposr(a5),d0 ; get scanline
cmp.b #$ff,d0 ; reached line $ff?
bne.s ready_wait ; not yet
bsr animate_pacman ; animate pacman sprite
move.b $bfe001,d0 ; read hardware register
btst #7,d0 ; fire-button = bit 7
bne.s ready_wait ; not pressed - wait again!
lea gfx_buffer,a0
lea screen+(40*110)+12,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 16*26(a0),a0
lea 40*256(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
rts
************ pause game ************
pause_game:
lea screen+(40*110)+12,a0
lea gfx_buffer,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a0),a0
lea 16*26(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea pause_gfx,a0
lea screen+(40*110)+12,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
ps_wait:
move.b $bfec01,d0 ; read keyboard
eor.b #$ff,d0
ror.b #1,d0
cmp.b #$19,d0 ; is 'p' still pressed?
beq.s ps_wait ; wait till it's released
ps_wait2:
move.b $bfec01,d0
eor.b #$ff,d0
ror.b #1,d0
cmp.b #$19,d0 ; is 'p' pressed?
bne.s ps_wait2 ; wait till it is again
ps_wait3:
move.b $bfec01,d0
eor.b #$ff,d0
ror.b #1,d0
cmp.b #$19,d0 ; is 'p' still pressed?
beq.s ps_wait3 ; wait till it's not!!!
lea gfx_buffer,a0
lea screen+(40*110)+12,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 16*26(a0),a0
lea 40*256(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
rts
************ game over ************
game_over:
lea screen+(40*110)+12,a0
lea gfx_buffer,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a0),a0
lea 16*26(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #24,$64(a5) ; A channel modulo
move.w #0,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea game_over_gfx,a0
lea screen+(40*110)+12,a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 40*256(a1),a1
bsr blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
game_over_wait:
move.b vhposr(a5),d0 ; get scanline
cmp.b #$ff,d0 ; reached line $ff?
bne.s game_over_wait ; not yet
bsr animate_pacman ; animate pacman sprite
move.b $bfe001,d0 ; read hardware register
btst #7,d0 ; fire-button = bit 7
bne.s game_over_wait ; not pressed - wait again!
lea gfx_buffer,a0
lea screen+(40*110)+12,a1
bsr.s blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
lea 16*26(a0),a0
lea 40*256(a1),a1
bsr.s blitter_wait ; wait for blitter
move.l a0,$50(a5) ; A channel = source
move.l a1,$54(a5) ; D channel = destination
move.w #0,$64(a5) ; A channel modulo
move.w #24,$66(a5) ; D channel modulo
move.w #$09f0,$40(a5) ; function = straight copy
move.w #0,$42(a5) ; second control word
move.l #$ffffffff,$44(a5) ; first & last word masks
move.w #8+64*26,$58(a5) ; size of blit & start!
rts
************ wait for blitter ************
blitter_wait:
btst #14,$2(a5) ; is blitter ready?
bne.s blitter_wait ; not yet!
rts
************ data ************
gfx_lib: dc.b 'graphics.library',0
even
gfx_base: dc.l 0
x: dc.w 0 ; x-coordinate of pacman
y: dc.w 0 ; y-coordinate of pacman
dx: dc.w 0 ; x-speed of pacman
dy: dc.w 0 ; y-speed of pacman
dir: dc.w 0 ; direction of pacman
dir2: dc.w 0 ; direction pacman wants to go in
pacman_anim: dc.w 0 ; pacman animation number
lives: dc.w 0 ; player's number of lives
score: dc.w 0 ; player's score
dir_tab:
dc.w -2,0,2,0,0,2,0,-2 ; pac's direction table
incdir mysource:pacman.s/
ready_gfx: incbin text1.raw
game_over_gfx: incbin text2.raw
pause_gfx: incbin text3.raw
gfx_buffer: ds.b 16*26*2 ; buffer so we can save what's
; under where we're drawing
numbers: incbin numbers.raw ; numbers graphics (for score)
sprite1: ds.l 18 ; control longword + 16 lines
; + zero longword
sprite2: ds.l 18
include pacman.spr_gfx.s ; pacman graphics (source)
screen: incbin pac_screen.raw
************ equates ************
** exec library offsets
forbid equ -132
permit equ -138
openlib equ -552
closelib equ -414
allocmem equ -198
freemem equ -210
** register offsets
bplcon0 equ $100
bplcon1 equ $102
bplcon2 equ $104
bpl1mod equ $108
bpl2mod equ $10a
bpl1pth equ $e0
bpl1ptl equ $e2
bpl2pth equ $e4
bpl2ptl equ $e6
bpl3pth equ $e8
bpl3ptl equ $ea
diwstrt equ $8e
diwstop equ $90
ddfstrt equ $92
ddfstop equ $94
dmacon equ $96
vhposr equ $6
spr0pth equ $120
spr0ptl equ $122
spr1pth equ $124
spr1ptl equ $126
spr2pth equ $128
spr2ptl equ $12a
spr3pth equ $12c
spr3ptl equ $12e
spr4pth equ $130
spr4ptl equ $132
spr5pth equ $134
spr5ptl equ $136
spr6pth equ $138
spr6ptl equ $13a
spr7pth equ $13c
spr7ptl equ $13e
colour0 equ $180
colour1 equ $182
colour2 equ $184
colour3 equ $186
colour4 equ $188
colour5 equ $18a
colour6 equ $18c
colour7 equ $18e
colour8 equ $190
colour9 equ $192
colour10 equ $194
colour11 equ $196
colour12 equ $198
colour13 equ $19a
colour14 equ $19c
colour15 equ $19e
colour16 equ $1a0
colour17 equ $1a2
colour18 equ $1a4
colour19 equ $1a6
colour20 equ $1a8
colour21 equ $1aa
colour22 equ $1ac
colour23 equ $1ae
colour24 equ $1b0
colour25 equ $1b2
colour26 equ $1b4
colour27 equ $1b6
colour28 equ $1b8
colour29 equ $1ba
colour30 equ $1bc
colour31 equ $1be
end